/**
 * 比较 KISSY Event 模块:
 * TODO: 
 * 1, Bug: 没考虑添加的 func 中有可能会移除自己的情况; 在 callback 中复制一份 queue 解决
 * 2, 添加: 移除一个 type 的全部 func 和 移除一个元素的所有事件
 * 3, 添加: 给一个元素添加很多事件 和 一个很多元素添加同样事件
 * 4, 改进: eles 和 eventPairs 用对象表示省去 callback 的闭包和 splice
 * 5, KISSY 绑定的 callback 是调用 Event._handle() 函数，保证了自定义事件的 fire
 */
function array_indexOf(arr, v) {
	if (!(arr instanceof Array)) {
		throw 'argument "arr" need to be an "Array"!';
	}
	if ([].indexOf) {
		return arr.indexOf(v);
	} else {
		var i = 0,
			len = arr.length;

		for (; i < len; ++i) {
			if (v == arr[i]) {
				return i;
			}
		}

		return -1;
	}
}

var Event = function(doc) {
	var eles  = []; // [ele, ele, ......]
	var eventPairs = [];
     /**
	  * [
	  *     {
	  *         'click', {
	  *             'queue': [func, func, ...]
	  *             'callback': fns
	  *         },
	  *         'mouseover', {
	  *             'queue': [func, func, ...]
	  *             'callback': fns
	  *         }
	  *     },
	  *     {
	  *         'click', {
	  *             'queue': [func, func, ...]
	  *             'callback': fns
	  *         },
	  *         'mouseover', {
	  *             'queue': [func, func, ...]
	  *             'callback': fns
	  *         }
	  *     }
	  * ]
      */

	var add = function() {
		if (doc.addEventListener) {
			return function(ele, eventType, func) {
				ele.addEventListener(eventType, func, false);
			};
		} else if (doc.attachEvent) {
			return function(ele, eventType, func) {
				ele.attachEvent('on' + eventType, func);
			};
		}
	}();
	var remove = function() {
		if (doc.removeEventListener) {
			return function(ele, eventType, func) {
				ele.removeEventListener(eventType, func, false);
			};
		} else if (doc.attachEvent) {
			return function(ele, eventType, func) {
				ele.detachEvent('on' + eventType, func);
			};
		}
	}();

	var pushFuncToQueue = function(idx, eventType, func) {
		var fns = eventPairs[idx][eventType]['queue'];
		if (array_indexOf(fns, func) === -1) { // 防止重复绑定
			fns.push(func);
		}
	};

	var addEventPair = function(idx, eventType, func, ele) {
		var pair = {};
		pair['queue']  = [func];
		pair['callback']  =  function(ele, queue) {
			return function(evt) {
				var i = 0,
					len = queue.length;

				for (; i < len; ++i) {
					var ret = queue[i].call(ele, evt);
					// 其中一个绑定的函数返回 false 则不会触发后面函数
					if (ret === false) {
						return;
					}
				}
			
			};
		}(ele, pair['queue']);

		eventPairs[idx][eventType] = pair;

		return pair;
	};

	var addListener = function(idx, eventType, func, ele) {
		if (idx === -1) { // 没注册过任何事件
			idx = eles.length;
			eles.push(ele);
			eventPairs.push({});
		}

		var pair = addEventPair(idx, eventType, func, ele);
		add(eles[idx], eventType, pair['callback']);
	};

	return {
		addEvent: function(ele, eventType, func) {
			var idx;

			if ((idx = array_indexOf(eles, ele)) !== -1 && typeof eventPairs[idx][eventType] !== 'undefined') { // 添加过该类型事件
				pushFuncToQueue(idx, eventType, func);
			} else { // 没添加过这种类型事件
				addListener(idx, eventType, func, ele);
			}
		},

		removeEvent: function(ele, eventType, func) {
			var idx = array_indexOf(eles, ele);
			if (idx === -1) { // 元素没有注册事件
				return;
			}

			var pairs = eventPairs[idx];
			var pair = pairs[eventType];
			if (typeof pair === 'undefined') { // 没有注册这种类型事件
				return;
			}

			var queue = pair['queue'];
			var num = array_indexOf(queue, func);
			if (num === -1) { // 没有注册这个函数
				return;
			}
			queue.splice(num, 1);

			if (queue.length === 0) { // 删除属性
				remove(ele, eventType, pair['callback']); // 移除绑定
				delete pairs[eventType];
			}

			var isEmptyEventPair = true;
			for (var p in eventPairs[idx]) {
				isEmptyEventPair = false;
			}
			if (isEmptyEventPair) {
				eventPairs.splice(idx, 1);
				eles.splice(idx, 1);
			}
		}
	};
}(document);
